
/****************************************************************************/
#include <stdio.h>

#include "M051Series.h"
#include "queue.h"
#include "ADC_CMP.h"




/****************************************************************************/
/***        Macro Definitions                                             ***/
/****************************************************************************/


/****************************************************************************/
/***        Type Definitions                                              ***/
/****************************************************************************/


/****************************************************************************/
/***        Local Function Prototypes                                     ***/
/****************************************************************************/

/****************************************************************************/
/***        Exported Variables                                            ***/
/****************************************************************************/

/****************************************************************************/
/***        Local Variables                                               ***/
/****************************************************************************/
volatile uint32_t g_u32AdcIntFlag;
volatile uint32_t g_u32AdcCmp0IntFlag;
volatile uint32_t g_u32AdcCmp1IntFlag;

uint16_t g_au16AdcData[BURST_COUNT] = {0};


CircQueue adc_dat_queue;
BOOL 	 bSampleFinish = FALSE;


/****************************************************************************/
/***        Exported Functions                                            ***/
/****************************************************************************/

/****************************************************************************/
/***        Local Functions                                               ***/
/****************************************************************************/


/****************************************************************************
 *
 * NAME: vQueue_Init
 *
 * DESCRIPTION:
 *
 * PARAMETERS:      Name            RW  Usage
 * None.
 *
 * RETURNS:
 * None.
 *
 * NOTES:
 * None.
 ****************************************************************************/
/*---------------------------------------------------------------------------------------------------------*/
/* ADC interrupt handler                                                                                   */
/*---------------------------------------------------------------------------------------------------------*/


void ADC_IRQHandler(void)
{
//    uint32_t u32OperationMode;
    
    if(ADC->ADSR & ADC_ADSR_ADF_Msk)
    {
		if(g_u32AdcCmp0IntFlag ==1)
		{
			uint16_t pos = uQueue_AddItem(&adc_dat_queue);
			g_au16AdcData[ pos ] = (uint16_t)_ADC_GET_CONVERSION_DATA(0);
		}
        ADC->ADSR = ADC_ADSR_ADF_Msk;      /* clear the A/D conversion flag */
    }
    
    if(ADC->ADSR & ADC_ADSR_CMPF0_Msk)
    {        
        _ADC_CLEAR_CMP0_INT_FLAG();     /* clear the A/D compare flag 0 */
		if(g_u32AdcCmp0IntFlag == 0 )
		{
		 	g_u32AdcCmp0IntFlag = 1;
			g_u32AdcCmp1IntFlag = 0;

			_ADC_CLEAR_CMP1_INT_FLAG();
			_ADC_ENABLE_CMP(1);

			vQueue_Flush(&adc_dat_queue);
			//

		}
    }
    
    if(ADC->ADSR & ADC_ADSR_CMPF1_Msk)
    {
        _ADC_CLEAR_CMP1_INT_FLAG();     /* clear the A/D compare flag 1 */
		if(g_u32AdcCmp1IntFlag == 0)
		{
		 	g_u32AdcCmp1IntFlag = 1;
			_ADC_DISABLE_CMP(1);
			bSampleFinish = TRUE;
			
		}
    }
}


/* ADC interrupt callback function of burst mode */
void AdcIntCallback()
{
    while(_ADC_IS_DATA_VALID(0)) /* Check the VALID bits */
    {
		uint16_t pos = uQueue_AddItem(&adc_dat_queue);
		g_au16AdcData[ pos ] = (uint16_t)_ADC_GET_CONVERSION_DATA(0);
    }
}


void AdcResultMonitorStart(void)
{
    /* Set the ADC operation mode as continuous scan, input mode as single-end and enable the ADC converter */
    ADC->ADCR = (ADC_ADCR_ADMD_CONTINUOUS | ADC_ADCR_DIFFEN_SINGLE_END | ADC_ADCR_ADEN_Msk);
    /* Set the ADC channel 0 */
    _ADC_ENABLE_CHANNEL(0);
    
    /* Enable ADC comparator 0. Compare condition: conversion result > 0x100; match Count=5. */

    _ADC_SET_CMP0(0, ADC_GREATER_OR_EQUAL, 0x400, 2);
	_ADC_ENABLE_CMP(0);
    /* clear the ADC comparator 0 interrupt flag for safe */
    _ADC_CLEAR_CMP0_INT_FLAG();
    /* enable ADC comparator 0 interrupt */
    _ADC_ENABLE_CMP_INT(0);



    /* Enable ADC comparator 1. Compare condition: conversion result >= 0x800; match Count=5. */
    _ADC_SET_CMP1(0, ADC_LESS_THAN, 0x400, 2);
    _ADC_DISABLE_CMP(1);
    /* clear the ADC comparator 1 interrupt flag for safe */
    _ADC_CLEAR_CMP1_INT_FLAG();
    /* enable ADC comparator 1 interrupt */
    _ADC_DISABLE_CMP_INT(1);


    
    NVIC_EnableIRQ(ADC_IRQn);
    /* Clear the ADC interrupt flag */
    ADC->ADSR = ADC_ADSR_ADF_Msk;      
    /* start A/D conversion */
    _ADC_START_CONVERT();

	vQueue_Init(&adc_dat_queue,BURST_COUNT);
}

void AdcResultMonitorEnd(void)
{
    /* Stop A/D conversion */
    _ADC_STOP_CONVERT();
    /* Disable ADC comparator interrupt */
    _ADC_DISABLE_CMP_INT(0);
    _ADC_DISABLE_CMP_INT(1);
    /* Disable compare function */
    _ADC_DISABLE_CMP(0);
    _ADC_DISABLE_CMP(1);
}




/****************************************************************************/
/***        END OF FILE                                                   ***/
/****************************************************************************/
